home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / CLASSSRC.PAK / GEOMETRY.CPP < prev    next >
C/C++ Source or Header  |  1997-05-06  |  4KB  |  200 lines

  1. //----------------------------------------------------------------------------
  2. // Borland WinSys Library
  3. // Copyright (c) 1993, 1997 by Borland International, All Rights Reserved
  4. //
  5. //$Revision:   5.6  $
  6. //
  7. // Implementation of classes for windowing system geometry
  8. //----------------------------------------------------------------------------
  9. #include <winsys/pch.h>
  10. #include <winsys/geometry.h>
  11.  
  12. #if defined(BI_NAMESPACE)
  13.  namespace ClassLib {
  14. #endif
  15.  
  16. //
  17. // Calculates the integer square root of a 32bit signed long. Returns a 16bit
  18. // signed. Is fairly fast, esp. compared to FP versions
  19. //
  20. int16 _BIDSFUNC
  21. Sqrt(int32 val)
  22. {
  23.   if (val <= 0)
  24.     return 0;     // Could throw a math exception?
  25.  
  26.   uint mask = 0x4000;   // Bit mask to shift right
  27.   int best = 0;         // Best estimate so far
  28.  
  29.   for (; mask; mask >>= 1)
  30.     if (((long)best+mask)*(best+mask) <= val)
  31.       best |= mask;
  32.  
  33.   return int16(best);
  34. }
  35.  
  36. #if defined(BI_NAMESPACE)
  37. }         // namespace ClassLib
  38. #endif
  39.  
  40. //
  41. // Return the distance between the origin and the point.
  42. //
  43. int TPoint::Magnitude() const
  44. {
  45.   return Sqrt(long(x)*long(x)+long(y)*long(y));
  46. }
  47.  
  48. //
  49. // Return the distance between the origin and the point.
  50. //
  51. int TSize::Magnitude() const
  52. {
  53.   return Sqrt(long(cx)*long(cx)+long(cy)*long(cy));
  54. }
  55.  
  56. //
  57. // Normalize the rectangle so that left is less than right and
  58. // top is less than bottom.
  59. //
  60. TRect&
  61. TRect::Normalize()
  62. {
  63.   if (left > right)
  64.     Swap(left, right);
  65.   if (top > bottom)
  66.     Swap(top, bottom);
  67.   return *this;
  68. }
  69.  
  70. //
  71. // Move the rectangle so that the new top left point is (left+dx, top+dy) and
  72. // the new bottom right point is (right+dx, bottom+dy).
  73. //
  74. TRect&
  75. TRect::Offset(int dx, int dy)
  76. {
  77.   left += dx;
  78.   top += dy;
  79.   right += dx;
  80.   bottom += dy;
  81.   return *this;
  82. }
  83.  
  84. //
  85. // Inflate the rectangle so that new top left point is (left-dx, top-dy) and
  86. // the new bottom right point is (right+dx, bottom+dy).
  87. //
  88. TRect&
  89. TRect::Inflate(int dx, int dy)
  90. {
  91.   left -= dx;
  92.   top -= dy;
  93.   right += dx;
  94.   bottom += dy;
  95.   return *this;
  96. }
  97.  
  98. //
  99. // Return the largest rectangle that is common to both rectangles.
  100. //
  101. TRect&
  102. TRect::operator &=(const TRect& other)
  103. {
  104.   if (!IsNull()) {
  105.     if (other.IsNull())
  106.       SetNull();
  107.     else {
  108.       left = Max(left, other.left);
  109.       top = Max(top, other.top);
  110.       right = Min(right, other.right);
  111.       bottom = Min(bottom, other.bottom);
  112.     }
  113.   }
  114.   return *this;
  115. }
  116.  
  117. //
  118. // Return the largest rectangle that contains both rectangles.
  119. //
  120. TRect&
  121. TRect::operator |=(const TRect& other)
  122. {
  123.   if (!other.IsNull()) {
  124.     if (IsNull())
  125.       *this = other;
  126.     else {
  127.       left = Min(left, other.left);
  128.       top = Min(top, other.top);
  129.       right = Max(right, other.right);
  130.       bottom = Max(bottom, other.bottom);
  131.     }
  132.   }
  133.   return *this;
  134. }
  135.  
  136. //
  137. // Determines the parts of this rect that do not lie within "other"
  138. //
  139. // Resulting rectangles are placed in the "result" array.
  140. //
  141. // Returns the resulting number of rectangles which will be in the
  142. // range "0 .. 4" inclusive
  143. //
  144. int
  145. TRect::Subtract(const TRect& other, TRect result[]) const
  146. {
  147.   // Case of non-intersection, result is just this rectangle
  148.   //
  149.   if (!Touches(other)) {
  150.     result[0] = *this;
  151.     return 1;
  152.   }
  153.   // Check for up to four sub-rectangles produced
  154.   //
  155.   else {
  156.     int  i = 0;
  157.  
  158.     // Top piece of this rect
  159.     //
  160.     if (other.top > top) {
  161.       result[i].left = left;
  162.       result[i].top = top;
  163.       result[i].right = right;
  164.       result[i].bottom = other.top;
  165.       i++;
  166.     }
  167.  
  168.     // Bottom piece of this rect
  169.     //
  170.     if (other.bottom < bottom) {
  171.       result[i].left = left;
  172.       result[i].top = other.bottom;
  173.       result[i].right = right;
  174.       result[i].bottom = bottom;
  175.       i++;
  176.     }
  177.  
  178.     // Left piece of this rect
  179.     //
  180.     if (other.left > left) {
  181.       result[i].left = left;
  182.       result[i].top = max(top, other.top);
  183.       result[i].right = other.left;
  184.       result[i].bottom = min(bottom, other.bottom);
  185.       i++;
  186.     }
  187.  
  188.     // Right piece of this rect
  189.     //
  190.     if (other.right < right) {
  191.       result[i].left = other.right;
  192.       result[i].top = max(top, other.top);
  193.       result[i].right = right;
  194.       result[i].bottom = min(bottom, other.bottom);
  195.       i++;
  196.     }
  197.     return i;
  198.   }
  199. }
  200.